package server.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import messages.ServerParameters;
import messages.ServerServerMessage;

public class InThread extends Thread {
	private Socket socket;
	private ObjectInputStream sInput;
	private ObjectOutputStream sOutput;
	private ServerInIF server;
	private ArrayList<ServerParameters> ServerList;
	private boolean KeepGoing = true;
	private ServerParameters inServer;

	// private SimpleDateFormat simpleDateFormat;

	public InThread(Socket socket, ObjectInputStream sInput, ServerInIF server) {
		this.socket = socket;
		this.sInput = sInput;
		this.server = server;
		// simpleDateFormat = server.getSimpleDateFormat();
		try {
			inServer = (ServerParameters) sInput.readObject();
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			server.display(getDate() + " Exception recive Server parameters: " + e1);
			this.disconnect();
		}
		// server.display(getDate() + " recive input server parameters" +
		// inServer.getAddress() + ": " + inServer.getPort());

		server.addInServer(inServer);

		try { // create output stream
			sOutput = new ObjectOutputStream(this.socket.getOutputStream());
		} catch (IOException e) {
			server.display(getDate() + " Exception creating new output Streams: " + e);
			this.disconnect();
			return;
		}

		ServerList = server.getMyServerList();

		try {
			sOutput.writeObject(ServerList);
		} catch (IOException e) {
			server.display(getDate() + " Exception doing login: " + e);
			this.disconnect();
		}
		
		server.broadcast(ServerList);
		server.display(getDate() + " Connection complead whith: " + inServer.getAddress()
				+ "/" + inServer.getPort());
	}

	public void run() {
		while (KeepGoing) {
			ServerServerMessage message = null;

			try {
				message = (ServerServerMessage) sInput.readObject();

			} catch (ClassNotFoundException | IOException e) {
				server.display(getDate() + " Exception receive data: " + e.toString()
						+ " disconnect from: " + inServer.getAddress() + "/"
						+ inServer.getPort());

				this.disconnect();
				break;
			}
			if (message != null) {
				String msg = " ";
				if (message.getMessageType() == ServerServerMessage.SERVERLIST) {
					for (ServerParameters parameters : message.getServerList()) {
						msg = msg + " " + parameters.getAddress() + "/"
								+ parameters.getPort() + "::"
								+ parameters.getNumberOfClients();
					}
				}
				server.display(getDate() + " Message from "
						+ message.getParameters().getAddress() + "/"
						+ message.getParameters().getPort() + ":" + message.getCounter()
						+ " " + msg);

				server.setSSMsg(message);
			} else {
				System.out.println(getDate() + " Received null");
			}
		}
	}

	public boolean writeMsg(ServerServerMessage msg) {
		if (!socket.isConnected()) {
			disconnect();
			return false;
		}
		try {
			sOutput.writeObject(msg);
		}
		// if an error occurs, do not abort just inform the user
		catch (IOException e) {
			server.display(getDate() + " Exception send data: " + e.toString()
					+ " disconnect from: " + inServer.getAddress() + "/"
					+ inServer.getPort());
			this.disconnect();
			// server.display(getDate() + " " + e.toString());
		}
		return true;
	}

	public void disconnect() {
		try {
			if (sInput != null) {
				sInput.close();
			}
		} catch (IOException e) {
		}
		try {
			if (sOutput != null) {
				sOutput.close();
			}
		} catch (IOException e) {
		}
		try {
			if (socket != null) {
				socket.close();
			}
		} catch (IOException e) {
		}
	}

	public String getDate() {
		return "InThread";
	}
}
